package cc.lj.internal.coupons.domain.martcap.service.impl;

import cc.lj.internal.core.exception.ServiceException;
import cc.lj.internal.core.model.PageBean;
import cc.lj.internal.core.model.PageParam;
import cc.lj.internal.coupons.domain.martcap.model.vo.CapBatchDO;
import cc.lj.internal.coupons.domain.martcap.model.vo.CapMerchantDO;
import cc.lj.internal.coupons.domain.martcap.model.vo.MartCapDO;
import cc.lj.internal.coupons.domain.martcap.model.vo.MultipleModelDO;
import cc.lj.internal.coupons.domain.martcap.model.vo.convert.CapMerchantDOConvertPO;
import cc.lj.internal.coupons.domain.martcap.repository.ICapMerchantRepository;
import cc.lj.internal.coupons.domain.martcap.service.ICapBatchDomainService;
import cc.lj.internal.coupons.domain.martcap.service.ICapMerchantDomainService;
import cc.lj.internal.coupons.domain.martcap.service.IMartCapDomainService;
import cc.lj.internal.coupons.domain.martcap.service.IMultipleModelDomainService;
import cc.lj.internal.coupons.infrastructure.excepion.CoupousExceptionEnum;
import cc.lj.internal.coupons.infrastructure.po.CapMerchantPO;
import cc.lj.internal.coupons.interfaces.dto.command.CapMerchantClearValueCommand;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class ICapMerchantDomainServiceImpl implements ICapMerchantDomainService {

    @Resource(name = "capMerchantRepository")
    private ICapMerchantRepository capMerchantRepository;

    //封顶额活动领域层
    @Resource(name = "martCapDomainServiceImpl")
    private IMartCapDomainService martCapDomainService;

    //倍数模型表领域层
    @Resource(name = "IMultipleModelDomainServiceImpl")
    private IMultipleModelDomainService modelDomainService;

    //封顶额批次
    @Resource(name = "capBatchDomainServiceImpl")
    private ICapBatchDomainService capBatchDomainService;
    /**
     * 将一个倍数模型下的所有商户封顶额清零
     * @param capMerchantClearValueCommand
     * @return
     */
    @Override
    public Integer clearMerchantValue(CapMerchantClearValueCommand capMerchantClearValueCommand) {
        Integer row = capMerchantRepository.updateClearValue(capMerchantClearValueCommand);
        return row;
    }

    /**
     * 查询一个倍数模型下商户封顶额总和
     * @param capMerchantDO
     * @return
     */
    @Override
    public Integer getValueSum(CapMerchantDO capMerchantDO) {

        return capMerchantRepository.getValueSum(CapMerchantDOConvertPO.INSTANCE.convert(capMerchantDO));
    }

    @Override
    public Integer save(CapMerchantDO capMerchantDO) {
        CapMerchantPO capMerchantPO = CapMerchantDOConvertPO.INSTANCE.convert(capMerchantDO);
        return capMerchantRepository.insert(capMerchantPO);
    }

    @Override
    public PageBean<CapMerchantDO> selectPage(PageParam<CapMerchantDO> pageParam) {
        PageInfo<CapMerchantPO> pageInfo = capMerchantRepository.selectPage(pageConvert(pageParam));

        List<CapMerchantDO> list = new ArrayList();
        for (CapMerchantPO entityPO : pageInfo.getList()) {
            CapMerchantDO entityDO = CapMerchantDOConvertPO.INSTANCE.convert(entityPO);
            list.add(entityDO);
        }
        //list的po转换为do后再组装PageBean将其返回上一层
        PageBean pageBean = PageBean.createPageBean(pageInfo.getPageNum(),
                pageInfo.getPageSize(), pageInfo.getTotal(), list);
        return pageBean;
    }

    @Override
    public Integer deleteById(Integer id) {
        //通过主键查询商户
        CapMerchantPO capMerchantPO = capMerchantRepository.getById(id);

        //通过主键查询封顶额活动,如果活动已结束则不允许删除
        MartCapDO martCapDO = martCapDomainService.getById(capMerchantPO.getCapId());
        if(martCapDO.getIsOver() == 1) {
            throw new ServiceException(CoupousExceptionEnum.MART_ENDED_NOTDELETE_MERCHANT);
        }
        //如果活动已开始，且该商户封顶额>0, 则不可删除
        if(martCapDO.getIsStart() == 1 && capMerchantPO.getMartCapValue().floatValue()>0) {
            throw new ServiceException(CoupousExceptionEnum.MART_STARTED_NOTDELETE_MERCHANT);
        }
        //删除操作
        return capMerchantRepository.deleteById(id);
    }

    @Override
    public Integer createCapValue(Integer id) {
        //通过主键查询商户表
        CapMerchantPO capMerchantPO = capMerchantRepository.getById(id);
        if(capMerchantPO.getMartCapValue().floatValue()>0) {
            throw new ServiceException(CoupousExceptionEnum.MERCHANT_CREATEED_CAP_VALUE);
        }
        //通过主键查询封顶额活动,如果活动已结束则不允许生成
        MartCapDO martCapDO = martCapDomainService.getById(capMerchantPO.getCapId());
        if(martCapDO.getIsOver() == 1) {
            throw new ServiceException(CoupousExceptionEnum.MART_ENDED_NOT_CREATE_CAPVALUE);
        }
        //通过主键查询倍数模型表数据
        MultipleModelDO modelDO = modelDomainService.getById(capMerchantPO.getModelId());

        /**
         * 计算商户封顶额  四舍五入取整(每日租金*租金倍数*天数)
         */
        //最后四舍五入取整
        Integer capValue = computeCapValue(modelDO.getMultipleNum(), modelDO.getDayNum(), capMerchantPO.getDayRent());

        //修改商户表的封顶额字段
        CapMerchantPO updateCapMerchantPO = new CapMerchantPO();
        updateCapMerchantPO.setId(id);
        updateCapMerchantPO.setMartCapValue(capValue);
        capMerchantRepository.updateById(updateCapMerchantPO);
        return capValue;
    }

    /**
     * 计算商户封顶额
     * @param mutipleNum 租金倍数
     * @param dayNum 活动天数
     * @param dayRent 日租金
     * @return 商户封顶额
     */
    private Integer computeCapValue(BigDecimal mutipleNum,Integer dayNum, BigDecimal dayRent) {
        //租金倍数*活动天数
        BigDecimal floatCapValue1 = mutipleNum.multiply(new BigDecimal(dayNum));
        log.info("计算商户封顶额度--租金倍数"+mutipleNum+"*活动天数"+dayNum+"="+floatCapValue1);
        //租金倍数*活动天数*每日租金
        BigDecimal floatCapValue2 = floatCapValue1.multiply(dayRent);
        log.info("计算商户封顶额度--租金倍数*活动天数*每日租金"+dayRent+"="+floatCapValue2);
        //最后四舍五入取整
        Integer capValue = floatCapValue2.setScale(0, BigDecimal.ROUND_HALF_UP).intValue();
        log.info("最终商户封顶额四舍五入取整后="+capValue);
        return capValue;

    }

    @Override
    public Integer batchCreateCapValue(Integer modelId) {
        //通过主键查询倍数模型表数据
        MultipleModelDO modelDO = modelDomainService.getById(modelId);

        //通过主键查询封顶额活动,如果活动已结束则不允许生成
        MartCapDO martCapDO = martCapDomainService.getById(modelDO.getCapId());
        if(martCapDO.getIsOver() == 1) {
            throw new ServiceException(CoupousExceptionEnum.MART_ENDED_NOT_CREATE_CAPVALUE);
        }

        //通过倍数模型表主键和封顶额字段=0查询商户数据
        CapMerchantPO queryMerchantPO = new CapMerchantPO();
        queryMerchantPO.setMartCapValue(0);
        queryMerchantPO.setModelId(modelId);
        List<CapMerchantPO> list = capMerchantRepository.getList(queryMerchantPO);
        //该倍数模型下没有选择商户或者全部商户都已经生成封顶额的情况,不允许继续生成
        if(list.size() == 0) {
            throw new ServiceException(CoupousExceptionEnum.MODEL_NOT_NOCAPVALUE_MERCHANT);
        }

        Integer totalCapValue = 0; //本次生成的总封顶额
        //遍历商户list，批量生成封顶额
        for (CapMerchantPO capMerchantPO : list) {
            //计算封顶额
            Integer capValue = computeCapValue(modelDO.getMultipleNum(), modelDO.getDayNum(), capMerchantPO.getDayRent());
            //修改商户表对应封顶额字段
            CapMerchantPO updateCapMerchantPO = new CapMerchantPO();
            updateCapMerchantPO.setId(capMerchantPO.getId());
            updateCapMerchantPO.setMartCapValue(capValue);
            capMerchantRepository.updateById(updateCapMerchantPO);
            totalCapValue+=capValue;
        }
        return totalCapValue;
    }

    @Override
    public List<Integer> getResourceIdListByModelId(Integer capId) {
        //通过倍数模型表主键查询商户表
        CapMerchantPO capMerchantPO = new CapMerchantPO();
        capMerchantPO.setCapId(capId);
        List<CapMerchantPO> merchantPOS = capMerchantRepository.getList(capMerchantPO);

        //定义商户合同签订表主键list
        List<Integer> contractIdList = new ArrayList<>();
        for (CapMerchantPO merchantPO : merchantPOS) {
            contractIdList.add(merchantPO.getResourceId());
        }
        return contractIdList;
    }

    @Override
    public List<CapMerchantDO> getList(CapMerchantDO capMerchantDO) {
        CapMerchantPO capMerchantPO = CapMerchantDOConvertPO.INSTANCE.convert(capMerchantDO);
        List<CapMerchantPO> list = capMerchantRepository.getList(capMerchantPO);
        List<CapMerchantDO> listDO = new ArrayList<>();
        for (CapMerchantPO merchantPO : list) {
            listDO.add(CapMerchantDOConvertPO.INSTANCE.convert(merchantPO));
        }
        return listDO;
    }

    /**
     * 分页DO to PO
     * @param pageParam
     * @return
     */
    public PageParam<CapMerchantPO> pageConvert(PageParam<CapMerchantDO> pageParam) {
        PageParam<CapMerchantPO> pageParamR = new PageParam<>();
        pageParamR.setPageNum( pageParam.getPageNum() ) ;
        pageParamR.setPageSize( pageParam.getPageSize() );
        pageParamR.setOrderBy( pageParam.getOrderBy() );
        CapMerchantPO entityPO = CapMerchantDOConvertPO.INSTANCE.convert(pageParam.getParam());
        pageParamR.setParam(entityPO);
        return pageParamR;
    }
}
